<template>
	<div style="border:1px solid #e0e0e0">
		<Toolbar :editor="editor" :default-config="toolbarConfig" :mode="mode" />

		<div @click="bodyClick">
			<Editor v-model="html" style="min-height:400px; background:#fff" :default-config="editorConfig" :mode="mode" @on-created="onCreated" @on-change="onChange" />
		</div>
	</div>
</template>

<script setup>
import { getCurrentInstance, ref, watch } from "vue";
import { Editor, Toolbar } from "@wangeditor/editor-for-vue";

const { proxy } = getCurrentInstance();

import { post, upload } from "../utils";
import { baseURL } from "../utils/request";

const props = defineProps({
	value: {
		type: String,
		required: true,
		default: ""
	}
});

const editor = ref();
const toolbarConfig = ref({
	//显示菜单
	toolbarKeys: [
		"undo",
		"redo",
		"headerSelect",
		"|",
		"bold",
		"underline",
		"italic",
		"color",
		"bgColor",
		"|",
		"indent",
		"delIndent",
		"justifyLeft",
		"justifyCenter",
		"justifyRight",
		"justifyJustify",
		"|",
		"fontSize",
		"fontFamily",
		"lineHeight",
		"|",
		"bulletedList",
		"numberedList",
		"todo",
		"insertLink",
		"insertTable",
		"|",
		"codeBlock",
		"divider",
		"uploadImage"

		/*
		{
			key: "group-more-style",
			title: "更多",
			iconSvg: '<svg viewBox="0 0 1024 1024"><path d="M204.8 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M505.6 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path><path d="M806.4 505.6m-76.8 0a76.8 76.8 0 1 0 153.6 0 76.8 76.8 0 1 0-153.6 0Z"></path></svg>',
			menuKeys: ["through", "code", "sup", "sub", "clearStyle"]
		}
		*/
	],
	//隐藏菜单
	excludeKeys: [],
	insertKeys: {
		//插入位置
		index: 0,
		keys: []
	},
	modalAppendToBody: false
});

const html = ref();

const mode = ref("default");

const emit = defineEmits(["update:value", "uploadImage"]);
const onChange = e => {
	//注册组件的update:value方法
	emit("update:value", editor.value.getHtml());
};

const customUpload = async (file, insertFn) => {
	const { host, accessid, signature, policy, key, url } = await post(`${baseURL}/util/oss?token=${proxy.$cookies.get("token")}`, { name: file.name });
	const formData = new FormData();
	formData.append("key", key);
	formData.append("OSSAccessKeyId", accessid);
	formData.append("policy", policy);
	formData.append("signature", signature);
	//成功后返回的操作码
	formData.append("success_action_status", 200);

	//放到最后，否则会报错
	formData.append("file", file);

	upload(host, formData, {
		Authorization: null
	}).then(() => {
		insertFn(url);
	});

	//自定义上传
	emit("uploadImage", file, insertFn);
};

const editorConfig = {
	placeholder: "请输入内容...",
	/*
	autoFocus: true,
	readOnly: true,
	*/
	MENU_CONF: {
		uploadImage: {
			customUpload
		}
	}
};

/*
子组件加载的时候，会到父组件中获取对应v-model:value值，这个加载动作只执行一次。
如果父组件通过request异步获取数据，子组件加载的时候，父组件有可能还没有获取到数据，因此props.value有可能会为空。

当父组件v-model:value值发生变化后，会通知子组件。子组件通过watch实时获取父组件最新的数据。
*/
watch(
	() => props.value,
	value => {
		//如果父组件和子组件的值一致，则无需变动
		if (html.value === value) return;

		html.value = value;
	},
	{ immediate: true, deep: true }
);

const onCreated = e => {
	editor.value = Object.seal(e);
	html.value = props.value;

	//只读
	//editor.value.disable();
};

const bodyClick = () => {
	if (!editor.value.isFocused()) {
		editor.value.blur();
		//光标移动到末尾
		editor.value.focus(true);
	}
	return false;
};

//输出组件方法，供外部调用
/*
const editorRef = ref();
<a-editor ref="editorRef"></a-editor>

editorRef.value.bodyClick();
*/
defineExpose({
	bodyClick
});
</script>

<style src="@wangeditor/editor/dist/css/style.css"></style>

<style scoped lang="scss">
:deep(.w-e-toolbar) {
	border-bottom: 1px solid rgba(0, 0, 0, 0.05);
}
:deep(.w-e-bar-item) {
	button {
		font-size: 12px;
		height: 24px;
		line-height: 24px;
		border-radius: 4px;
		padding: 0 5px;

		&:hover {
			background-color: rgb(237, 242, 255);
		}
	}
}

:deep(.w-e-bar-divider) {
	height: 20px;
	margin-top: 10px;
}

:deep(.w-e-bar) {
	font-size: 12px;
}

:deep(.w-e-text-container) {
	h1 {
		font-size: 26px;
		font-weight: 800;
	}
	h2 {
		font-size: 22px;
		font-weight: 800;
	}
	h3 {
		font-size: 20px;
		font-weight: 800;
	}
	h4 {
		font-size: 18px;
		font-weight: 800;
	}
	h5 {
		font-size: 16px;
		font-weight: 800;
	}
	div,
	p {
		font-size: 14px;
	}
}
:deep(.w-e-select-list) {
	background: linear-gradient(0deg, rgb(255, 255, 255), rgb(255, 255, 255)) padding-box, rgb(196, 196, 196);
	box-shadow: rgba(0, 0, 0, 0.1) 5px 5px 30px;
	border: 1px solid rgba(209, 209, 209, 0.71);
	border-radius: 6px;
	max-height: calc(100vh - 130px);

	ul li {
		line-height: 30px;
		padding: 0px 12px;
		white-space: nowrap;
		font-size: 12px;
		color: rgb(57, 66, 89);

		&:hover {
			background-color: rgb(245, 246, 247);
		}

		svg {
			fill: rgb(83, 131, 254);
			right: 18px;
			left: auto;
			width: 10px;
		}
	}
}

:deep(.w-e-bar-item-menus-container) {
	background: linear-gradient(0deg, rgb(255, 255, 255), rgb(255, 255, 255)) padding-box, rgb(196, 196, 196);
	box-shadow: rgba(0, 0, 0, 0.1) 5px 5px 30px;
	border: 1px solid rgba(209, 209, 209, 0.71);
	border-radius: 6px;
	max-height: calc(100vh - 130px);
	padding: 5px 0;

	.w-e-bar-item {
		padding: 0;
		height: 30px;

		button {
			height: 30px;
			color: rgb(57, 66, 89);

			justify-content: flex-start;
			//flex-grow：放大比例（默认为0，即如果存在剩余空间也不放大）
			//flex-shrink：缩小比例（默认为1，即如果空间不足将缩小）
			//flex-basis：定义在分配多余空间之前占据的主轴空间

			//flex: 1 = flex: 0 1 auto（默认不放大，放不下了缩小，优先采用自己本身宽度）
			flex: 1 0 auto;
			padding: 0 16px;

			&:hover {
				background-color: rgb(245, 246, 247);
			}
		}
	}
}

:deep(.w-e-text-container) div {
	input[type="radio"],
	input[type="checkbox"] {
		vertical-align: middle;
		margin: -1px 0 1px;
	}
}
</style>
